package HTTP

import (
	"SQL/FSDB"
	"database/sql"
	"logs"
	"net/http"
)

type GroupSessionRow struct {
	GroupID    string `json:"GroupID"`
	GroupName  string `json:"GroupName"`
	GroupIcon  string `json:"GroupIcon"`
	SenderID   string `json:"SenderID"`
	SenderName string `json:"SenderName"`
	MsgID      string `json:"MsgID"`
	Msg        string `json:"Msg"`
	CreateTime string `json:"CreateTime"`
	UnreadNum  int    `json:"UnreadNum"`
}

func sessionListWithGroup(w http.ResponseWriter, req *http.Request) {

	var resCode = http.StatusOK
	var msg = ""
	var res interface{}
	defer func() {
		writeResult(w, resCode, msg, res)
	}()

	userID := req.FormValue("userID")

	ok := false
	if ok, resCode, msg = isArgsEmpty(userID); ok {
		return
	}
	if ok, resCode, msg = isValidID(userID, "UserID"); !ok {
		return
	}

	errCode, errMsg, msgRows := groupSession(userID)
	msg = errMsg
	if errCode != Success {
		resCode = errCode
		return
	}
	res = msgRows
}

func groupSession(userID string) (errCode int, errMsg string, list interface{}) {

	tx, err := FSDB.BeginTx()
	if err != nil {
		return errEndTx, "FSDB.BeginTx 执行错误：" + err.Error(), nil
	}
	defer func() {
		if errCode == Success {
			tx.Commit()
			return
		}
		err := tx.Rollback()
		if err != nil {
			errCode = errEndTx
			errMsg = err.Error()
			logs.Print("*groupSession tx.Rollback err:", err.Error())
		}
	}()

	lastOnlineTimeSQL := `
						SELECT lastOnlineTime FROM users
						WHERE id = $1;
						`
	// 获取当前用户最后在线的时间
	lotStmt, lastOnlineTimeRows, err := FSDB.QueryTx(tx, lastOnlineTimeSQL, userID)
	defer lotStmt.Close()
	defer lastOnlineTimeRows.Close()
	if err != nil {
		return errEndTx, "lastOnlineTimeSQL tx.QueryTx 执行错误：" + err.Error(), nil
	}

	if !lastOnlineTimeRows.Next() {
		return errEndTx, "从数据库读取用户的最后一次在线时间失败！", nil
	}
	var lastOnlineTime string
	err = lastOnlineTimeRows.Scan(&lastOnlineTime)
	if err != nil {
		return errEndTx, "lastOnlineTimeRows.Scan 执行错误：" + err.Error(), nil
	}
	lastOnlineTimeRows.Close()

	// 获取群组列表
	groupListSQL := `
				SELECT groupid
				FROM members mem
				WHERE mem.userid = $1;`

	glStmt, groupListRows, err := FSDB.QueryTx(tx, groupListSQL, userID)
	defer glStmt.Close()
	defer groupListRows.Close()
	if err != nil {
		return errEndTx, "groupListSQL QueryTx执行错误：" + err.Error(), nil
	}

	sessionRows := make(map[string]GroupSessionRow, 0)

	groupList := make([]string, 0)
	for groupListRows.Next() {
		var groupID string
		err = groupListRows.Scan(&groupID)
		if err != nil {
			return errEndTx, "groupListRows.Scan执行错误：" + err.Error(), nil
		}
		groupList = append(groupList, groupID)
	}
	groupListRows.Close()

	for _, groupID := range groupList {
		errCode, errMsg = getGroupSessionInContext(tx, userID, groupID, lastOnlineTime, sessionRows)
	}

	// 更新时间的责任交给群会话接口
	updateTimeSQL := `UPDATE users
					  SET lastOnlineTime = $1
					  WHERE id = $2`
	_, err = tx.Exec(updateTimeSQL, currentTime(), userID)
	if err != nil {
		return errEndTx, "updateTimeSQL Exec出错，err:" + err.Error(), sessionRows
	}

	if len(sessionRows) == 0 {
		return Success, "成功获取 " + userID + " 的群会话列表！", nil
	}
	sessionList := make([]GroupSessionRow, 0)
	for _, session := range sessionRows {
		if len(session.SenderID) == 0 { //群里面没有消息
			continue
		}
		sessionList = append(sessionList, session)
	}

	return Success, "成功获取 " + userID + " 的群会话列表！", sessionList
}

func getGroupSessionInContext(tx *sql.Tx, userID string, groupID string, lastOnlineTime string, sessionRows map[string]GroupSessionRow) (errCode int, errMsg string) {

	// 获取会话里最后一条消息的相关信息
	lastMsgSQL := `
				SELECT
						m.sender AS senderID,
						o.nickname AS senderName,
						m.id AS msgID,
						m.content AS msg,
						createTime
				FROM messages m,objects o
				WHERE receiver = $1 
					AND o.id = m.sender
				ORDER BY createTime DESC
				LIMIT 1;`

	lmStmt, lastMsgRows, err := FSDB.QueryTx(tx, lastMsgSQL, groupID)
	defer lmStmt.Close()
	defer lastMsgRows.Close()

	if err != nil {
		return errEndTx, "lastMsgSQL QueryTx执行错误：" + err.Error()
	}

	for lastMsgRows.Next() {
		var senderID = ""
		var senderName = ""
		var msgID = ""
		var msg = ""
		var createTime = ""
		err := lastMsgRows.Scan(&senderID, &senderName, &msgID, &msg, &createTime)
		if err != nil {
			return errEndTx, "lastMsgRows.Scan 执行错误：" + err.Error()
		}
		sessionRow := GroupSessionRow{
			GroupID:    groupID,
			GroupName:  "",
			GroupIcon:  "",
			SenderName: senderName,
			SenderID:   senderID,
			MsgID:      msgID,
			Msg:        msg,
			CreateTime: createTime,
			UnreadNum:  0,
		}
		sessionRows[groupID] = sessionRow
	}
	lastMsgRows.Close()

	// 获取群组的信息
	groupInfoSQL := `
					SELECT  groupp.id AS groupID,
							groupp.nickname  AS groupName,
							groupp.icon AS groupIcon
					FROM objects groupp
					WHERE groupp.id = $1;`

	giStmt, groupInfoRows, err := FSDB.QueryTx(tx, groupInfoSQL, groupID)
	defer giStmt.Close()
	defer groupInfoRows.Close()
	if err != nil {
		return errEndTx, "talkerInfoSQL QueryTx执行错误：" + err.Error()
	}

	for groupInfoRows.Next() {
		var groupID = ""
		var groupName = ""
		var groupIcon = ""
		err = groupInfoRows.Scan(&groupID, &groupName, &groupIcon)
		if err != nil {
			return errEndTx, "groupInfoRows.Scan 执行错误：" + err.Error()
		}
		sessionRow := GroupSessionRow{
			GroupID:    groupID,
			GroupName:  groupName,
			GroupIcon:  groupIcon,
			SenderID:   sessionRows[groupID].SenderID,
			SenderName: sessionRows[groupID].SenderName,
			MsgID:      sessionRows[groupID].MsgID,
			Msg:        sessionRows[groupID].Msg,
			CreateTime: sessionRows[groupID].CreateTime,
			UnreadNum:  0,
		}
		sessionRows[groupID] = sessionRow
	}
	groupInfoRows.Close()

	//获取未读消息数
	unreadNumSQL := `
				SELECT  COUNT(m.id) AS unreadNum
				FROM messages m
				WHERE  m.receiver = $1
						AND m.sender <> $2
						AND createTime > $3;`

	unStmt, unreadNumRows, err := FSDB.QueryTx(tx, unreadNumSQL, groupID, userID, lastOnlineTime)
	defer unStmt.Close()
	defer unreadNumRows.Close()
	if err != nil {
		return errEndTx, "unreadNumSQL QueryTx执行错误：" + err.Error()
	}

	for unreadNumRows.Next() {
		var unreadNum = 0
		err := unreadNumRows.Scan(&unreadNum)
		if err != nil {
			return errEndTx, "unreadNumRows.Scan 执行错误：" + err.Error()
		}

		sessionRow := GroupSessionRow{
			GroupID:    groupID,
			GroupName:  sessionRows[groupID].GroupName,
			GroupIcon:  sessionRows[groupID].GroupIcon,
			SenderID:   sessionRows[groupID].SenderID,
			SenderName: sessionRows[groupID].SenderName,
			MsgID:      sessionRows[groupID].MsgID,
			Msg:        sessionRows[groupID].Msg,
			CreateTime: sessionRows[groupID].CreateTime,
			UnreadNum:  unreadNum,
		}
		sessionRows[groupID] = sessionRow
	}
	unreadNumRows.Close()

	return Success, "成功获取 " + userID + " 的群会话列表！"
}

/*
群聊：
请求 userID
返回（groupID,groupName,groupIcon,
	senderID,senderName,msgID,msg,createTime,unreadNum）




-- GROUP WHICH CURRENT USER PARTICIPATED IN
CREATE VIEW groupView AS
SELECT groupid
FROM members mem
WHERE mem.userid = 10001;


-- GROUP INFO
SELECT  groupp.id AS groupID,
		groupp.nickname  AS groupName,
		groupp.icon AS groupIcon
FROM groupView,objects groupp
WHERE groupp.id = groupView.groupid;


-- LAST MSG FOR GROUP
SELECT  groupView.groupid,
		m.sender AS senderID,
		o.nickname AS senderName,
		m.id AS msgID,
		m.content AS msg,
		createTime
FROM groupView,messages m,objects o
WHERE receiver = groupView.groupid
	AND o.id = m.sender
ORDER BY createTime DESC
LIMIT 1;


-- UNREAD MSG NUM IN GROUP FOR CURRENT USER
SELECT  mem.groupID,
        COUNT(m.id) AS unreadNum
FROM groupView mem
INNER JOIN messages m
	ON  m.receiver = mem.groupid
        AND m.sender <> 10001
        AND createTime > '2017-04-20 07:47:03.670000'
GROUP BY mem.groupID;


DROP VIEW groupView;
*/
